Inside Solaris logo
The Cobb Group This article is reprinted from the November 1996 issue of  Inside Solaris, a monthly publication of The Cobb Group.

Click for a FREE issue!


Using command-line history in the Korn shell

By Al Alexander

Recently, someone cornered me and asked why UNIX doesn’t provide command-line history like DOS does. In DOS, after you execute the DOSKEYS command, you can recall and edit command lines. Actually, UNIX does provide a similar capability. As I spend most of my day working at the command line in the Korn shell, life with Solaris would be far more difficult without the command-line history feature.

However, command-line history works differently depending on which shell you’re using. In this article, we’ll show you how to enable and use command-line history in the Korn shell. Next month, we’ll show you how to use command-line history in the C shell.

Enabling command-line history

The Korn shell provides a very sophisticated command-line history mechanism. Using it, you can retrieve previously entered commands, as well as edit and execute them. You can use two primary modes, vi and emacs mode. (There’s also a gmacs mode, but it’s nearly identical to emacs mode.)

These modes allow you to edit the com-mand line as if you were using the editor named. For example, in vi mode, the Korn shell uses insert and command modes for the editor, just like vi. To enter command mode, you press the [Esc] key. Then you can use the normal cursor-movement keys for moving around and editing text. You can go back to insert mode by pressing i, a, or A, just as you’d expect. Table A shows a subset of the editing commands you can use in vi and emacs modes.

Table A: These are some of the most-commonly used command-line editing commands in vi and emacs.

Description vi (insert mode) vi (command mode) emacs
Retrieve next command n/a j [Ctrl]-N
Retrieve previous command n/a k [Ctrl]-P
Move left one character n/a h [Ctrl]-B
Move right one character n/a l [Ctrl]-F
Move left one word n/a b [Esc]b
Move right one word n/a w [Esc]f
Enter insert mode n/a i, a, A n/a
Exit insert mode [Esc] n/a n/a
Go to start of line n/a ^ [Ctrl]-A
Go to end of line n/a $ [Ctrl]-E
Execute command [Enter] [Enter] [Enter]
Delete current character n/a x [Ctrl]-D
Delete current word n/a dw [Esc]d

If you use either vi or emacs as your editor-of-choice, it’s easy to select which mode to use. If you use another editor, like the CDE text editor, you’ll just have to choose the one you like better. It may be worthwhile checking them both out.

It’s very easy to enable the command-line history feature in the Korn shell. All you need to do is set the environment variable VISUAL to the mode you’d like to use: emacs, gmacs, or vi. Let’s try it out. If you’re not already in the Korn shell, enter it by typing

$ ksh

Now let’s enable the command-line editing mode. For this demonstration, we’ll use vi mode.

$ VISUAL=vi

To demonstrate the re-use of previously entered commands, let’s first create a brief three-command history. Type in the following three UNIX commands, and then we’ll show how to easily re-use these commands within the Korn shell:

$ ls -al
$ ps -ef
$ who

Now that we’ve put some commands in your history, let’s call up the last command we entered, who. To do so, press the [Esc] key, then press k. You should then see the who command, with the cursor on the w. At this point, you’re in a one-line version of the vi editor. The history list is treated like a file, and your command line is like a one-line view port into this file. You begin in vi’s insert mode, so pressing the [Esc] key puts the editor into command mode. Pressing the k key moves you up a line to the previous command. If you press k again, you’ll go up to another com-mand, in this case ps -ef. Press k again, and you’ll see the ls -al command again. Press j to go to the next command, and you’ll be back at the ps -ef command.

As in the regular vi editor, typing a capital A allows you to append to the end of the current line. Go ahead and type a capital letter A, then type:

| more

Now your command line should look like this:

$ ls -al | more

You can execute the command by pressing the [Enter] key.

The capabilities you just saw are some of the things that make this feature so desirable. The vi editor offers many other capabilities, such as searching for previous commands with the / character, that make the command-history editing feature very powerful. Just as the vi editing mode is powerful, emacs mode provides similar features.

Once you enable the command-line history editing mode, you not only gain the ability to retrieve previous commands and edit them, you also get the ability to edit the line you’re currently working on. If you’ve entered 30 or so characters and notice that the first character is wrong, you can simply go to the start of the line, edit the character, then go back to the end and continue typing.

Terminal requirements

For the in-place command-line editing to work, your terminal must support two basic features. First, your terminal must not automatically advance to the next line when it receives a carriage return without a new line. Second, when your terminal prints a space, it must overwrite the character that was originally at the location. These two features allow you to use in-place command-line editing by allowing the terminal to update the command line as it’s being edited.

Editing a very long line

As a result of the modest requirements the in-place command-line editing feature places on your terminal, the Korn shell uses only one physical line when you edit a command line. As you notice, the terminal isn’t required to have a character used to move the cursor up a line. Since the cursor motion is limited to left (via the carriage return), right (by printing characters), and down (via the new line), the Korn shell uses a single line on your terminal. Otherwise, in-place editing for long command lines would be impossible. When you’re editing a command line larger than the width of your terminal, the Korn shell displays a special character at the right margin to tell you so.

If you’re at the start of the long command line, the Korn shell displays a > at the right margin to show you that there’s more command line to the right. If you’re at the end of the long command line, you’ll see a <, showing you that there’s more command line to the left of the left margin. If your command line is so large that it extends past both the left and right margins, the Korn shell will display an * at the right margin.

Unless you tell it otherwise, the Korn shell assumes that your terminal is 80 characters wide. You can specify the size by setting the COLUMNS variable. Let’s try an example just to see how the Korn shell handles a very long line. We’re going to use the vi editing mode in this example. First, let’s start the Korn shell, set vi mode for command-line editing, and set the column width to 40 so we don’t have to use an exorbitantly long command line:

$ ksh
$ VISUAL=vi
$ COLUMNS=40

Now, let’s enter a relatively long command line:

$ now is the time for all good men to come to the aid of their party.

When you enter this command line, you’ll see it in its entirety, even if it wraps to the next line. Now press the [Esc] key, then the k key to invoke the command-line editor. When you do so, you’ll see

$ now is the time for all good men to>

The > symbol indicates that the command line extends past the right margin. If you use the L key to advance the cursor to the space after the word to, you’ll see

$ r all good men to come to the aid o*

Now, press A to start editing at the end of the line. When you do, you’ll see

$ id of their party.         <

The command-line history

If you’d like to examine the last few commands you’ve entered, you can type

$ history

This will print the last few commands that you’ve entered.

Each time you start the Korn shell, it loads the command-line history from the previous session. This makes life much simpler if you tend to do the same operations over and over. Rather than having to type them in again, you can access the commands you used in a pre-vious session.

Unless you override it, UNIX stores your command-line history in the file .sh_history. You may override it by setting the HISTFILE environment variable to the name of the file you’d rather use. You can use this feature to set up different command-line histories for different terminal windows. Thus, if you tend to work on multiple projects at once, like most of us, you can have a different command-line history for each project. You can even create a text file of commands you like to use, then load them.

You can also tell UNIX just how much history you want to store by setting the HISTSIZE variable. This tells how many commands will be available to you between sessions. Normally, this defaults to 128 commands.

Conclusion

UNIX provides three different, but related, mechanisms for giving you the ability to work with a command-line history. In this article, we’ve explored command-line history for the Korn shell. Next month, we’ll take a look at command-line history in the C shell.

Alvin J. Alexander is an independent consultant specializing in UNIX and the Internet. He has worked on UNIX networks to support the space shuttle, international clients, and various Internet service providers. He has provided UNIX and Internet training to over 400 clients in the last three years.

 

[The Cobb Group Home Page]

Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.

Questions? Comments?